<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>函数</title>
</head>

<body>

</body>

</html>
<script>
    //声明一个'fun1'的函数
    fun1()//函数提升
    function fun1() {
        console.log('函数fun1成功被调用');
    }
    fun1()
    //封装了一个‘fun2’的函数，进行加法运算
    function fun2(a, b) {
        return a + b
    }
    console.log(fun2(10, 20));// 10 20 是实参
    // 实参如果是基本数据类型(number,string,bol)，在函数中修改形参的值不影响原数据，如果是(arr,obj)等引用数据类型，会改变数据类型
    let a = 10
    function fun3(n) {
        n++
        console.log(n);
    }
    fun3(a)
    console.log(a);

    let obj = { name: '张三', age: 18 }
    function fun4(info) {
        info.name = '李四'
    }
    fun4(obj);
    console.log(obj);
    // 变量式声明函数
    let fun6 = function () {
        console.log('成功调用我了！！！！！！！！');
    }
    fun6();
    //匿名函数 自调用函数

    (function (a, b) {
        console.log('我是匿名函数被调用了');
        console.log(a + b);
    })(10, 20)
    //参数作用域
    function fun7(a, b) {
        console.log(a, b);
    }
    //console.log(b);//全局变量无法调用局部变量
    //参数默认值
    function fun8(str, num) {
        num = num == undefined ? 0 : num;
        str = str || '我是默认值';
        console.log(str, '------', num);
    }
    fun8('ok', 20)//不传实参，则用默认值，传实参，则用传的值
    //对位传参
    function fun9(name, age, sex, job, hight) {
        console.log(`姓名：${name}---年龄：${age}---性别${sex}----工作：${job}----身高${hight}`);

    }
    fun9('张三', 18, '男', '敲代码', 150)
    //arfuments对象

    function fun10() {
        console.log(arguments);//arguments是一个伪数组，有数组的下标和长度，但不能使用数组的方法
        let a = Array.prototype.slice.call(arguments);//用数组原型链中方法将伪数组转换为真正的数组
        console.log(a);
        let sum = a.reduce(function (per, cur) {
            return per += cur
        }, 0)
        // let num = 0
        // for(let i=0;i<arguments.length;i++){
        //     num += arguments[i]
        // }
        console.log(sum);
    }
    fun10(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    //函数返回值
    let num = 5
    function fun11() {
        console.log('有输出');
        return [1,2,4,6,8]
        console.log('没输出');
    }
   console.log(fun11());

   //闭包函数
   function fun12(){
    let i = 10
    console.log(i);
      function fun13(){//对父级作用域变量的操作 计算后会储存在内存中，下次计算会直接从内存中取值
        i = i+1
        console.log(i);
    }
    return fun13
   }
   let fun12Back=fun12()
   fun12Back()
   fun12Back()
   fun12Back()
   let num1 = 10,num2=20
   function fun13(){
    console.log(num1+num2);
   }
   fun13()
   function fun14(a,b,type){
    let num1 = a,num2=b
    switch(type){
        case '+': 
        return function() {
            console.log(`num1+num2=${num1 + num2} `);
        }
    }
   }
   let fun14Back=fun14(10,20,'+');
   fun14Back()
   // 递归函数
   function fun15(n){
    console.log(n);
    if(n<=1){
        return 1
    }else{
       // return n * fun15(n-1)//耦合度高
       return n * arguments.callee(n-1)
    }
   }
   fun15(15)
   console.log(fun15(15));
</script>